#pragma once
#include<iostream>
#include<string>
#include<assert.h>
#include<functional>
#include<pthread.h>

class Thread;

struct Data
{
    Thread* _this;
    void* _args;

    Data(): _this(nullptr),_args(nullptr) {}
    ~Data(){}
};

class Thread
{
    public:
        typedef std::function<void*(void*)> func_t;
        const int num = 1024;
    
    public:
        Thread(func_t func,void* args = nullptr,int number=0):_func(func),_args(args)
        {
            char buffer[num];
            snprintf(buffer,sizeof buffer,"thread->%d",number);
            _name = buffer;
            Data* d = new Data();
            d->_this = this;
            d->_args = _args; 

            //int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
            //如果start_routine在类中，第一个参数是this指针，不符合规则，所以start_routine应该设为static
            int n = pthread_create(&_tid,nullptr,start_routine,d);
            assert(n);
            (int)n;
        }

        static void* start_routine(void* args)
        {
            Data* d = static_cast<Data*>(args);
            void* ret = d->_this->run(d->_args);
            delete d;
            return ret;
        }

        void* run(void* args){return _func(args);}
        void join() {int n = pthread_join(_tid,nullptr);assert(n);(int)n;}

    private:
        std::string _name;
        func_t _func;
        void* _args;
        pthread_t _tid;
};